#ifndef BUFFER_H
#define BUFFER_H
#include <vector>
#include <iostream>
#include <string>
#include <atomic>
#include <assert.h>
#include <unistd.h>
#include <sys/uio.h>
class Buffer
{
public:
    Buffer(int initBufferSize = 1024);
    ~Buffer() = default;
    // 缓存区中可以读取的字节个数
    size_t readableBytes() const;
    // 缓冲区中可以写入的字节个数
    size_t writeableBytes() const;
    // 缓冲区中已经读取的字节数
    size_t readBytes() const;

    // 获取当前读指针
    const char *curReadPtr() const;
    // 获取当前写指针
    const char *curWritePtrConst() const;
    char *curWritePtr();

    // 更新读指针
    void updateReadPtr(size_t len);
    void updateReadPtrUntilend(const char *end); // 将读指针更新到指定位置
    // 更新写指针
    void updateWritePtr(size_t len);
    // 将写指针和读指针初始化
    void initPtr();

    // 保证将数据写入缓冲区
    void ensureWriteable(size_t len);
    // 将数据写到缓冲区
    void append(const char *str, size_t len);
    void append(const std::string &str);
    void append(const void *data, size_t len);
    void append(const Buffer &buffer);

    // I/O操作的读与写接口
    ssize_t readFd(int fd, int *Erron); // 返回从文件描述符 fd 中实际读取的字节数
    ssize_t writeFd(int fd, int *Erron);

    // 将缓冲区数据转化为字符串
    std::string AlltoStr();
    // test
    void printContent()
    {
        std::cout << "pointer location info:" << readPos_ << " " << writePos_ << std::endl;
        for (size_t i = readPos_; i <= writePos_; ++i)
        {
            std::cout << buffer_[i] << " ";
        }
        std::cout << std::endl;
    }

private:
    char *BeginPtr_(); // 返回指向缓冲区初始位置的指针
    const char *BeginPtr_() const;
    void allocateSpace(size_t len);     // 缓冲区空间不够时扩容
    std::vector<char> buffer_;          // buffer实体用来存储char类型的数据
    std::atomic<std::size_t> readPos_;  // 用于指示读指针
    std::atomic<std::size_t> writePos_; // 用于指示写指针
};
#endif
